package com.yugao.fintech.antelope.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yugao.fintech.antelope.base.security.utils.SecurityUtils;
import com.yugao.fintech.antelope.system.assembly.LogAssembly;
import com.yugao.fintech.antelope.system.mapper.SysOperateLogMapper;
import com.yugao.fintech.antelope.system.model.entity.SysOperateLog;
import com.yugao.fintech.antelope.system.model.rqrs.log.OperateLogDeleteReq;
import com.yugao.fintech.antelope.system.model.rqrs.log.OperateLogPageReq;
import com.yugao.fintech.antelope.system.model.rqrs.log.OperateLogSaveReq;
import com.yugao.fintech.antelope.system.service.SysOperateLogService;
import com.yugao.fintech.framework.assistant.utils.DateUtils;
import com.yugao.fintech.framework.assistant.utils.StringUtils;
import com.yugao.fintech.framework.mybatisplus.utils.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SysOperateLogServiceImpl implements SysOperateLogService {
    @Autowired
    private SysOperateLogMapper operateLogMapper;
    @Autowired
    private LogAssembly logAssembly;

    /**
     * 新增操作日志
     * 
     * @param req 操作日志对象
     * @return 结果
     */
    @Override
    public boolean save(OperateLogSaveReq req) {
        req.setUserName(SecurityUtils.getUserName());
        return operateLogMapper.insert(logAssembly.toOperateLog(req)) > 0;
    }

    @Override
    public IPage<SysOperateLog> pageOperateLog(OperateLogPageReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<SysOperateLog> lqw =  SysOperateLog.lqw()
                .eq(StringUtils.isNotEmpty(req.getTraceId()), SysOperateLog::getTraceId, req.getTraceId())
                .like(StringUtils.isNotEmpty(req.getTag()), SysOperateLog::getTag, req.getTag())
                .eq(StringUtils.isNotEmpty(req.getStatus()), SysOperateLog::getStatus, req.getStatus())
                .ge(Objects.nonNull(beginTime), SysOperateLog::getCreatedAt, beginTime)
                .le(Objects.nonNull(endTime), SysOperateLog::getCreatedAt, endTime)
                .orderByDesc(SysOperateLog::getCreatedAt);
        
        IPage<SysOperateLog> pageRq = PageUtil.to(req);
        return operateLogMapper.selectPage(pageRq, lqw);
    }

    /**
     * 查询系统操作日志集合
     * 
     * @param rq 操作日志对象
     * @return 操作日志集合
     */
    @Override
    public List<SysOperateLog> listOperateLog(SysOperateLog rq) {
        return operateLogMapper.selectList(getLqw(rq));
    }

    private LambdaQueryWrapper<SysOperateLog> getLqw(SysOperateLog rq) {
        return SysOperateLog.lqw()
                .eq(StringUtils.isNotEmpty(rq.getTraceId()), SysOperateLog::getTraceId, rq.getTraceId())
                .like(StringUtils.isNotEmpty(rq.getTag()), SysOperateLog::getTag, rq.getTag());
    }

    /**
     * 批量删除系统操作日志
     * 
     * @param operateIds 需要删除的操作日志ID
     * @return 结果
     */
    @Override
    public boolean deleteBatch(Long[] operateIds) {
        return operateLogMapper.deleteBatchIds(Arrays.stream(operateIds).collect(Collectors.toList())) == operateIds.length;
    }

    @Override
    public boolean delete(OperateLogDeleteReq operateLogDeleteReq) {
        Integer beforeDays = operateLogDeleteReq.getBeforeDays();
        Date date = DateUtils.addDays(new Date(), beforeDays);
        LambdaQueryWrapper<SysOperateLog> wrapper = SysOperateLog.lqw()
                .le(SysOperateLog::getCreatedAt, date);
        return operateLogMapper.delete(wrapper) > 0;
    }

    /**
     * 查询操作日志详细
     * 
     * @param operateId 操作ID
     * @return 操作日志对象
     */
    @Override
    public SysOperateLog get(Long operateId) {
        return operateLogMapper.selectById(operateId);
    }

    /**
     * 清空操作日志
     */
    @Override
    public void clear() {
        operateLogMapper.cleanOperateLog();
    }
}
